package de.mlp_distributed.mlp.core;

import de.mlp_distributed.mlp.math.mahout.Vector;

public enum CostFunction {

	// TODO SQUARD_ERROR for regression in combination with linear squashing
	CROSS_ENTROPY_INDEPENDENT_OUTPUTS {
		@Override
		/**
		 * E = sum_o ( t_o ln(y_o) * (1-t_o ln (1-y_o))
		 * with sum_o: sum over all output units  
		 */
		public double getCost(final Vector output, final Vector target) {
			double e = 0;
			// TODO make this numerically more stable
			// log(0) = - infinity => should be avoided
			for (int i = 0; i < output.size(); i++) {
				if (target.getQuick(i) == output.getQuick(i)) {
					continue;
				}
				if (target.get(i) == 1) {
					e -= Math.log(output.get(i));
				} else if (target.get(i) == 0) {
					e -= Math.log(1 - output.get(i));
				}
			}
			return e;
		}
	},
	CROSS_ENTROPY_MUTUALLY_EXCUSIVE_OUTPUTS {
		@Override
		public double getCost(final Vector output, final Vector target) // throws
		// InvalidArgumentException
		{
			double e = 0;
			// TODO make this numerically more stable
			// log(0) = - infinity => should be avoided
			for (int i = 0; i < output.size(); i++) {
				if (target.get(i) == 1) {
					e -= Math.log(output.get(i));
				}
			}
			return e;
		}
	};
	/**
	 * get the cost for the error function without regularization cost
	 * 
	 * @param output
	 * @param target
	 * @return
	 * 
	 */
	public abstract double getCost(Vector output, Vector target);// throws
	// InvalidArgumentException;
}
